<template>
<div>
    <Row :gutter="8">
        <Col span="24">
            <label>时间单位：</label>
            <Select v-model="time_option.selected_unit" style="width:100px">
                <Option value="date">天</Option>
                <Option value="month">月</Option>
                <Option value="year">年</Option>
            </Select>
            <label>日期：</label>
            <DatePicker v-model="time_option.date_range[0]" :type="time_option.selected_unit" placeholder="Select date" style="width: 120px"></DatePicker>
            <label>至</label>
            <DatePicker v-model="time_option.date_range[1]" :type="time_option.selected_unit" placeholder="Select date" style="width: 120px"></DatePicker>
            <Button type="primary" @click="handleStatistics">统计</Button>
            <div style="float:right">
                <label>数据源：</label>
                <Select v-model="time_option.data_source" style="width:100px">
                    <Option v-for="(item, key) in time_option.data_source_map" :value="key" :key="key">{{ item }}</Option>
                </Select>
                <label>图表类型：</label>
                <Select v-model="time_option.chart_type" style="width:100px">
                    <Option value="line">折线图</Option>
                    <Option value="area">面积堆叠图</Option>
                </Select>
            </div>
            <Alert v-if="time_option.warning_alert.value" type="warning" show-icon closable>{{ time_option.warning_alert.message }}</Alert>
            <x-charts :option="time_option_data"></x-charts>
            <Table :columns="columns" stripe border :data="table_data" height="400"></Table>
            <!-- <Tabs value="name1" type="card">
                <TabPane label="按时间统计" name="name1">
                </TabPane>
                <TabPane label="按地区统计" name="name2">
                </TabPane>
            </Tabs> -->
        </Col>
    </Row>
</div>
</template>

<script>
import Parent from '../Parent'
// 导入chart组件
import XCharts from '@/common/components/XCharts.vue'

export default {
    extends: Parent,
    components:{
        XCharts
    },
    data() {
        var temp_begin_date = new Date();
        var temp_end_date = new Date();
        temp_begin_date.setDate(temp_begin_date.getDate() - 20);
        return {
            time_option: {
                data_source: "member",
                data_source_map: {
                    member: "注册会员量",
                    service: "发布服务量",
                    demand: "发布需求量",
                    abutment: "已服务量"
                },
                chart_type: "line",
                selected_unit: "date",
                date_range: [temp_begin_date, temp_end_date],
                warning_alert: {
                    value: false,
                    message: ""
                }
            },
            areas: [
                { full_name: "河北省,秦皇岛市,海港区", name: "海港区" },
                { full_name: "河北省,秦皇岛市,北戴河区", name: "北戴河区" },
                { full_name: "河北省,秦皇岛市,抚宁区", name: "抚宁区" },
                { full_name: "河北省,秦皇岛市,山海关区", name: "山海关区" },
                { full_name: "河北省,秦皇岛市,昌黎县", name: "昌黎县" },
                { full_name: "河北省,秦皇岛市,卢龙县", name: "卢龙县" },
                { full_name: "河北省,秦皇岛市,青龙满族自治县", name: "青龙满族自治县" },
                { full_name: "其他地区", name: "其他地区" }
                //{ full_name: "合计", name: "合计" }
            ],
            primary_data: [],
            filter_data: {}
        };
    },
    computed: {
        time_data_source_key() {
            return this.time_option.data_source+"_count";
        },
        columns() {
            var temp = [{
                title: "日期", key: "date"
            }];
            this.areas.forEach( area => {
                temp.push({
                    title: area.name, render: (h, params) => {
                        var num = params.row[area.full_name][this.time_data_source_key];
                        return h("div", { attrs: { class: num == 0 ? "zero-cell" : "" } }, num);
                    }
                });
            });
            temp.push({
                title: "合计", fixed: 'right', render: (h, params) => {
                    var temp_total = this.areas.reduce((total, area) => {
                        return total + params.row[area.full_name][this.time_data_source_key];
                    }, 0);
                    return h("div", { attrs: { class: temp_total == 0 ? "zero-cell" : "" } }, temp_total);
                }
            });
            return temp;
        },
        table_data() {
            var temp = [];
            for(var key in this.filter_data) {
                temp.push(this.filter_data[key]);
            }
            var last_row = { date: "合计" };
            this.areas.forEach( area => {
                last_row[area.full_name] = {};
                var temp_total = 0;
                for(var key in this.filter_data) {
                    var elem = this.filter_data[key];
                    temp_total += elem[area.full_name][this.time_data_source_key];
                }
                last_row[area.full_name][this.time_data_source_key] = temp_total;
            });
            temp.push(last_row);
            return temp;
        },
        // 绘制图表所需要的数据
        time_option_data() {
            var result = this.filter_data;
            var categories = Object.keys(result);
            var count_key = this.time_data_source_key;
            var series = this.areas.map( area => {
                return {
                    name: area.name,
                    data: categories.reduce((arr, key, index) => {
                        arr[index] = result[key][area.full_name][count_key];
                        return arr;
                    }, new Array(categories.length))
                }
            });
            return {
                chart: { type: this.time_option.chart_type },
                title: { text: '秦皇岛各地区' + this.time_option.data_source_map[this.time_option.data_source] },
                xAxis: {
                    categories: categories,
                    tickmarkPlacement: 'on',
                    title: { enabled: false }
                },
                yAxis: {
                    title: { text: '数量' },
                },
                legend: {
                    layout: 'vertical',
                    align: 'right',
                    verticalAlign: 'middle'
                },
                plotOptions: {
                    series: { label: { connectorAllowed: false } },
                    area: {
                        stacking: 'normal',
                        lineColor: '#666666',
                        lineWidth: 1,
                        marker: { lineWidth: 1, lineColor: '#666666' }
                    }
                },
                series: series
            };
        }
    },
    methods: {
        //数据过滤函数，将后端返回的统计数据进行过滤和格式化，形成规范易读的数据格式
        getFilteData() {
            // 根据时间单位决定add_func和key_func
            var add_func, key_func;
            var result;
            var selected_unit = this.time_option.selected_unit;
            while(true) {
                var start_date = new Date(Date.parse(this.time_option.date_range[0]));
                var end_date = new Date(Date.parse(this.time_option.date_range[1]));
                switch(selected_unit) {
                    case "date": 
                        add_func = date => { return date.setDate(date.getDate()+1); }; 
                        key_func = (year, month, day) => { return year+'-'+month+'-'+day; };
                        break;
                    case "month":
                        add_func = date => { return date.setMonth(date.getMonth()+1); }; 
                        key_func = (year, month, day) => { return year+'-'+month; };
                        break;
                    case "year":
                        add_func = date => { return date.setYear(date.getFullYear()+1); };
                        key_func = (year, month, day) => { return year.toString(); };
                        break;
                }
                // 在开始和结束日期区间内，以时间单位为步长，填充各个时间的数据，这属于规范化数据
                result = {};
                var temp_num = 0;
                while(start_date <= end_date) {
                    if(++temp_num > 100) break;
                    var key = key_func(start_date.getFullYear(), start_date.getMonth() + 1, start_date.getDate());
                    result[key] = this.areas.reduce( (obj, area) => {
                        obj[area.full_name] = {
                            area: area.name,
                            demand_count: 0,
                            member_count: 0,
                            service_count: 0,
                            abutment_count: 0
                        };
                        return obj;
                    }, { date: key });
                    add_func(start_date);
                }
                if(temp_num > 100) {
                    if(selected_unit == "year") break;
                    this.time_option.warning_alert.value = true;
                    this.time_option.warning_alert.message = "所选择时间跨度太大，已使用更大时间单位显示数据";
                    if(selected_unit == "date") selected_unit = "month";
                    else if(selected_unit == "month") selected_unit = "year";
                    continue;
                }else if(temp_num == 1) {
                    if(selected_unit == "date") break;
                    this.time_option.warning_alert.value = true;
                    this.time_option.warning_alert.message = "所选择时间跨度位1，已使用更小时间单位显示数据";
                    if(selected_unit == "year") selected_unit = "month";
                    else if(selected_unit == "month") selected_unit = "date";
                    continue;
                }
                break;
            }
            this.time_option.selected_unit = selected_unit;
            // 在规范化的数据基础上，用数据库读到的数据对其进行覆盖，得到包含数据库数据的规范化数据形式
            this.api.post("statistics/oneMonth", { 
                date_unit: selected_unit, 
                begin_time: Date.parse(this.time_option.date_range[0]),
                end_time: Date.parse(this.time_option.date_range[1])
            },res=>{
                res.data.forEach( elem => {
                    var key = key_func(elem.year, elem.month, elem.day);
                    if(result[key]) {
                        var row = result[key];
                        if(row[elem.area]) {
                            row[elem.area].member_count += elem.member_count;
                            row[elem.area].demand_count += elem.demand_count;
                            row[elem.area].service_count += elem.service_count;
                            row[elem.area].abutment_count += elem.abutment_count;
                        }else {
                            row["其他地区"].member_count += elem.member_count;
                            row["其他地区"].demand_count += elem.demand_count;
                            row["其他地区"].service_count += elem.service_count;
                            row["其他地区"].abutment_count += elem.abutment_count;
                        }
                        //row["合计"][count_key] += elem[count_key];
                    }
                });
                this.filter_data = result;
            });
        },
        handleStatistics() {
            this.time_option.warning_alert.value = false;
            this.getFilteData();
        },
        getTestData() {
            var temp = { member: [], demand: [], service: [], abutment: [] };
            for(var i = 0; i < 100000; i++) {
                temp.member.push({ area: "河北省,秦皇岛市,海港区", create_date: 1000000000000 + parseInt(Math.random()*100000000)*1000, member_count: parseInt(Math.random()*100) });
                temp.demand.push({ area: "河北省,秦皇岛市,海港区", create_date: 1000000000000 + parseInt(Math.random()*100000000)*1000, demand_count: parseInt(Math.random()*100) });
                temp.service.push({ area: "河北省,秦皇岛市,海港区", create_date: 1000000000000 + parseInt(Math.random()*100000000)*1000, service_count: parseInt(Math.random()*100) });
                temp.abutment.push({ area: "河北省,秦皇岛市,海港区", create_date: 1000000000000 + parseInt(Math.random()*100000000)*1000, abutment_count: parseInt(Math.random()*100) });
            }
            return temp;
        }
    },
    created() {
        this.handleStatistics();
    }
}
</script>

<style>
.ivu-table .zero-cell {
    color: #ddd;
}
</style>

